package cn.janescott.framework.dubbo.utils;

import com.alibaba.dubbo.config.annotation.Reference;

import java.lang.reflect.Field;
import java.util.List;

/**
 * 属性手机工具类
 *
 * @author scott
 * @date 2019/02/12
 **/
public final class FieldCollectUtils {

    /**
     * 处理当前类的所有属性
     *
     * @param target
     * @param fields
     */
    public static void handleCurrentClass(Class target, List<Field> fields) {
        if (target != null) {
            Field[] declaredFields = target.getDeclaredFields();
            for (Field field : declaredFields) {
                Reference annotation = field.getAnnotation(Reference.class);
                if (null != annotation) {
                    fields.add(field);
                }
            }
        }
    }

    /**
     * 处理父类引用问题
     *   abstract class @Reference {@see NullPointException}
     *   info: objClz.getDeclaredFields() can only get all the field for current class, but cannot access the super class
     *   option 1: try to get superClass's field and set proxy bean at one of the Sons;
     *   option 2: handle the abstract superClass reference at end of bean initialization;
     * @author scott
     * @date 2019-02-01
     */
    public static void handleSuperClass(Class target, List<Field> fields) {
        if (target != null) {
            Class superclass = target.getSuperclass();
            if (superclass != null && !superclass.getSimpleName().equals(Object.class.getSimpleName())) {
                Field[] declaredFields = superclass.getDeclaredFields();
                if (declaredFields.length > 0) {
                    for (Field field : declaredFields) {
                        Reference reference = field.getAnnotation(Reference.class);
                        if (reference != null && !fields.contains(field)) {
                            fields.add(field);
                        }
                    }
                }
                handleSuperClass(superclass, fields);
            }
        }
    }

}
